﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Modeling.Diagrams;
using System.Drawing;
using Microsoft.VisualStudio.Modeling;
using devtm.AutoMapper.CustomCode.Shapes;
using CodeDomHelper.Types;
using CSharpParser.SCharpType;
using Microsoft.RestrictedUsage.CSharp.Semantics;
using devtm.AutoMapper.CustomCode.Helpers;

namespace devtm.AutoMapper
{
    
    public partial class MapperShape
    {




        private bool CtrlPressed = false;


        /// <summary>
        /// Gets the child compartment shape and verifies whether it can resize its parent compartment shape.
        /// </summary>
        /// <value></value>
        /// <returns>true if a child compartment shape can resize its parent compartment shape; otherwise, false.
        /// </returns>
        public override bool AllowsChildrenToResizeParent
        {
            get
            {
                // Overridden to return false so that the visual layout issue is solved, where a shape with a connector that "has custom source"
                // resizes to make the source shape wider until it reaches the edge of the referenced shape.
                // See http://social.msdn.microsoft.com/Forums/en-US/vsx/thread/4cc74f9e-1949-43ba-8407-934f6664167d.
                // It is applied to the base class here so that all inheriting compartment shapes automatically have this fix applied.
                return false;
            }
        }


        protected override void InitializeShapeFields(IList<ShapeField> shapeFields)
        {

            base.InitializeShapeFields(shapeFields);

        }

        
        public override void OnKeyDown(DiagramKeyEventArgs e)
        {
            base.OnKeyDown(e);
            CtrlPressed = e.Control;
        }

        public override void OnKeyUp(DiagramKeyEventArgs e)
        {
            base.OnKeyUp(e);
            CtrlPressed = e.Control;
        }

        public override void OnDoubleClick(DiagramPointEventArgs e)
        {
            base.OnDoubleClick(e);

            foreach (var itemMAP in e.HitDiagramItem.RepresentedElements)
            {

                ItemMap itemMap = itemMAP as ItemMap;

                if (itemMap != null)
                {

                    TypeExpression typeExpression = null;
                    if (CtrlPressed)
                        typeExpression = TypeExpression.Analyse(itemMap.Mapper.MappingDestination.TypeElement.AssemblyQualifiedName);
                    else
                        typeExpression = TypeExpression.Analyse(itemMap.Mapper.MappingSource.TypeElement.AssemblyQualifiedName);

                    VisualStudio.ParsingSolution.Project prj = Helpers.FindProject(this.Store, typeExpression);

                    if (prj != null)
                    {

                        var project = prj.Source;
                        if (project != null)
                        {

                            CSharpType sharpType = Parser.GetType(project, typeExpression.Namespace, typeExpression.Name);
                            if (sharpType != null)
                            {

                                CSharpMember member = null;
                                if (CtrlPressed)
                                    member = sharpType.GetMember(itemMap.TargetName);    
                                else
                                    member = sharpType.GetMember(itemMap.SourceName);    
                                

                                if (member != null)
                                    member.NavigateToSourceLocation();

                            }
                        }
                    }

                }


            }

        }

        protected override void InitializeDecorators(global::System.Collections.Generic.IList<ShapeField> shapeFields, global::System.Collections.Generic.IList<Decorator> decorators)
        {

            base.InitializeDecorators(shapeFields, decorators);

            //ShapeField field2 = ShapeElement.FindShapeField(shapeFields, "RefreshDecorator1");
            RefreshField field2 = new RefreshField("RefreshDecorator1");
            Decorator decorator2 = new ShapeDecorator((ShapeField)field2, ShapeDecoratorPosition.OuterTopLeft, new PointD(0, 0));
            decorators.Add(decorator2);

            //ShapeField field2 = ShapeElement.FindShapeField(shapeFields, "RefreshDecorator1");
            PineField field3 = new PineField("PineDecorator1");
            Decorator decorator3 = new ShapeDecorator((ShapeField)field3, ShapeDecoratorPosition.OuterTopLeft, new PointD(0.25, 0));
            decorators.Add(decorator3);
            
        }
     
  

        protected override CompartmentMapping[] GetCompartmentMappings(Type melType)
        {
           
            CompartmentMapping[] mappings = base.GetCompartmentMappings(melType);

            foreach (ElementListCompartmentMapping mapping in mappings)
            {
                mapping.ImageGetter = CompartmentImageProvider;
                
            }
            
            return mappings;

        }


        private Image CompartmentImageProvider(ModelElement element)
        {

            ItemMap item = element as ItemMap;

            if (item == null)
                return devtm.AutoMapper.Properties.Resources.None;

            if (!item.Enable)
                return devtm.AutoMapper.Properties.Resources.interdit;
           
            else if (item.SourceName == "this")
                return devtm.AutoMapper.Properties.Resources.Class162;

            else if (item.TypeCast == CastType.Custom)
                return devtm.AutoMapper.Properties.Resources.method16;

            else if (item.TypeCast == CastType.List)
                return devtm.AutoMapper.Properties.Resources.Liste;

            return devtm.AutoMapper.Properties.Resources.None;

        }


        public void MovesTypes()
        {

           
            Mapper mapper = ModelElement as Mapper;

            using (Transaction trans = mapper.Store.TransactionManager.BeginTransaction("reorder the diagram"))
            {

                foreach (BinaryLinkShape item in this.Link)
                {
                    if (item is LeftConnector)
                    {
                        LeftConnector left = item as LeftConnector;
                        TypeElementShape tl = left.FromShape as TypeElementShape;
                        tl.Location = new PointD(this.Location.X - tl.Size.Width - 1, this.Location.Y);
                    }
                    else if (item is RightConnector)
                    {
                        RightConnector right = item as RightConnector;
                        TypeElementShape tr = right.FromShape as TypeElementShape;
                        tr.Location = new PointD(this.Location.X + this.Size.Width + 1, this.Location.Y);

                    }
                }

                trans.Commit();
            }
        }


        //public bool Navigate(DiagramItem newFocusItem, SelectedShapesCollection selection)
        //{
        //    bool flag = false;
        //    if (selection == null)
        //    {
        //        return false;
        //    }
        //    if (newFocusItem != null)
        //    {
        //        if (!newFocusItem.Equals(selection.FocusedItem))
        //        {
        //            selection.FocusedItem = newFocusItem;
        //            flag = true;
        //        }
        //        Microsoft.VisualStudio.Modeling.Diagrams.Diagram diagram = this.Diagram;
        //        if (diagram != null)
        //        {
        //            DiagramView activeDiagramView = diagram.ActiveDiagramView;
        //            if ((activeDiagramView != null) && !newFocusItem.IsDiagram)
        //            {
        //                activeDiagramView.DiagramClientView.EnsureVisible(newFocusItem.AbsoluteBoundingBox, this.EnsureVisiblePreference);
        //            }
        //        }
        //    }
        //    return flag;
        //}



    }
     
    
}
